<?php

namespace Thenbsp\Wechat;

use Thenbsp\Wechat\Util\Curl;
use Thenbsp\Wechat\Util\Json;
use Thenbsp\Wechat\Exception\OAuthException;

/**
 * 网页授权
 * Created by thenbsp (thenbsp@gmail.com)
 * Created at 2015/07/23
 */
class OAuth
{
    /**
     * 获取授权 URL 接口
     */
    const AUTHORIZE_URL = 'https://open.weixin.qq.com/connect/oauth2/authorize';

    /**
     * 获取用户 AccessToken 接口
     */
    const ACCESS_TOKEN_URL = 'https://api.weixin.qq.com/sns/oauth2/access_token';

    /**
     * 公众号 APP ID
     */
    protected $appid;

    /**
     * 公众号 APP SECRET
     */
    protected $appsecret;

    /**
     * 构造方法
     */
    function __construct($appid, $appsecret)
    {
        $this->appid        = $appid;
        $this->appsecret    = $appsecret;
    }

    /**
     * 直接跳转到授权页
     */
    public function authorize($redirect_uri, $scope = 'snsapi_base', $state = null)
    {
        header('Location: '.$this->getAuthorizeURL($redirect_uri, $scope, $state));
    }

    /**
     * 获取授权 URL (http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html)
     */
    public function getAuthorizeURL($redirect_uri, $scope = 'snsapi_base', $state = null)
    {
        $params = [];
        $params['appid']            = $this->appid;
        $params['redirect_uri']     = $redirect_uri;
        $params['response_type']    = 'code';
        $params['scope']            = $scope;
        $params['state']            = $state;

        return static::AUTHORIZE_URL.'?'.http_build_query($params);
    }

    /**
     * 授权回调（通过 Code 换取 AccessToken）
     *
     */
    public function getAccessToken($code)
    {
        $params = array(
            'appid'         => $this->appid,
            'secret'        => $this->appsecret,
            'code'          => $code,
            'grant_type'    => 'authorization_code'
        );

        $curl       = new Curl;
        $response   = $curl->get(static::ACCESS_TOKEN_URL, $params);

        if( empty($response) ) {
            throw new OAuthException('Get AccessToken Failure: '.$curl->error());
        }

        $object = Json::decode($response);

        if( isset($object->access_token) &&
            isset($object->expires_in) &&
            isset($object->openid) ) {

            return $object;
        }

        throw new OAuthException($object->errcode.': '.$object->errmsg);
    }

}
